package com.cwnu.sw.cys.core.common.utils;

import cn.hutool.core.util.ObjectUtil;
import com.cwnu.sw.cys.core.common.exception.BusinessException;
import com.cwnu.sw.cys.core.common.exception.CommonErrorEnum;
import com.cwnu.sw.cys.core.common.exception.ErrorEnum;
import org.hibernate.validator.HibernateValidator;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import java.text.MessageFormat;
import java.util.*;
/**
 * 校验工具类
 *
 * @author jisam
 * @version 1.0
 * @contact "jisamchan@outlook.com"
 * @date 25/03/2025
 */
public class AssertUtil {

    /**
     * 校验到失败就结束的验证器
     */
    private static Validator failFastValidator = Validation.byProvider(HibernateValidator.class)
            .configure()
            .failFast(true)
            .buildValidatorFactory().getValidator();

    /**
     * 全部校验的验证器
     */
    private static Validator validator = Validation.buildDefaultValidatorFactory().getValidator();

    /**
     * 注解验证参数(校验到失败就结束)
     *
     * @param obj 待校验的对象
     * @param <T> 对象的类型
     */
    public static <T> void fastFailValidate(T obj) {
        Set<ConstraintViolation<T>> constraintViolations = failFastValidator.validate(obj);
        if (constraintViolations.size() > 0) {
            throwException(CommonErrorEnum.PARAM_VALID, constraintViolations.iterator().next().getMessage());
        }
    }

    /**
     * 注解验证参数(全部校验,抛出异常)
     *
     * @param obj 待校验的对象
     * @param <T> 对象的类型
     */
    public static <T> void allCheckValidateThrow(T obj) {
        Set<ConstraintViolation<T>> constraintViolations = validator.validate(obj);
        if (constraintViolations.size() > 0) {
            StringBuilder errorMsg = new StringBuilder();
            Iterator<ConstraintViolation<T>> iterator = constraintViolations.iterator();
            while (iterator.hasNext()) {
                ConstraintViolation<T> violation = iterator.next();
                // 拼接异常信息
                errorMsg.append(violation.getPropertyPath().toString()).append(":").append(violation.getMessage()).append(",");
            }
            // 去掉最后一个逗号
            throwException(CommonErrorEnum.PARAM_VALID, errorMsg.toString().substring(0, errorMsg.length() - 1));
        }
    }

    /**
     * 注解验证参数(全部校验,返回异常信息集合)
     *
     * @param obj 待校验的对象
     * @param <T> 对象的类型
     * @return 异常信息集合
     */
    public static <T> Map<String, String> allCheckValidate(T obj) {
        Set<ConstraintViolation<T>> constraintViolations = validator.validate(obj);
        if (constraintViolations.size() > 0) {
            Map<String, String> errorMessages = new HashMap<>();
            Iterator<ConstraintViolation<T>> iterator = constraintViolations.iterator();
            while (iterator.hasNext()) {
                ConstraintViolation<T> violation = iterator.next();
                errorMessages.put(violation.getPropertyPath().toString(), violation.getMessage());
            }
            return errorMessages;
        }
        return new HashMap<>();
    }

    /**
     * 如果不是true，则抛异常
     *
     * @param expression 表达式
     * @param msg 异常信息
     */
    public static void isTrue(boolean expression, String msg) {
        if (!expression) {
            throwException(msg);
        }
    }

    /**
     * 如果不是true，则抛异常
     *
     * @param expression 表达式
     * @param errorEnum 错误枚举
     * @param args 参数
     */
    public static void isTrue(boolean expression, ErrorEnum errorEnum, Object... args) {
        if (!expression) {
            throwException(errorEnum, args);
        }
    }

    /**
     * 如果是true，则抛异常
     *
     * @param expression 表达式
     * @param msg 异常信息
     */
    public static void isFalse(boolean expression, String msg) {
        if (expression) {
            throwException(msg);
        }
    }

    /**
     * 如果是true，则抛异常
     *
     * @param expression 表达式
     * @param errorEnum 错误枚举
     * @param args 参数
     */
    public static void isFalse(boolean expression, ErrorEnum errorEnum, Object... args) {
        if (expression) {
            throwException(errorEnum, args);
        }
    }

    /**
     * 如果不是非空对象，则抛异常
     *
     * @param obj 对象
     * @param msg 异常信息
     */
    public static void isNotEmpty(Object obj, String msg) {
        if (isEmpty(obj)) {
            throwException(msg);
        }
    }

    /**
     * 如果不是非空对象，则抛异常
     *
     * @param obj 对象
     * @param errorEnum 错误枚举
     * @param args 参数
     */
    public static void isNotEmpty(Object obj, ErrorEnum errorEnum, Object... args) {
        if (isEmpty(obj)) {
            throwException(errorEnum, args);
        }
    }

    /**
     * 如果不是非空对象，则抛异常
     *
     * @param obj 对象
     * @param msg 异常信息
     */
    public static void isEmpty(Object obj, String msg) {
        if (!isEmpty(obj)) {
            throwException(msg);
        }
    }

    /**
     * 如果两个对象不相等，则抛异常
     *
     * @param o1 对象1
     * @param o2 对象2
     * @param msg 异常信息
     */
    public static void equal(Object o1, Object o2, String msg) {
        if (!ObjectUtil.equal(o1, o2)) {
            throwException(msg);
        }
    }

    /**
     * 如果两个对象相等，则抛异常
     *
     * @param o1 对象1
     * @param o2 对象2
     * @param msg 异常信息
     */
    public static void notEqual(Object o1, Object o2, String msg) {
        if (ObjectUtil.equal(o1, o2)) {
            throwException(msg);
        }
    }

    /**
     * 判断对象是否为空
     *
     * @param obj 对象
     * @return 是否为空
     */
    private static boolean isEmpty(Object obj) {
        return ObjectUtil.isEmpty(obj);
    }

    /**
     * 抛出异常
     *
     * @param msg 异常信息
     */
    private static void throwException(String msg) {
        throwException(null, msg);
    }

    /**
     * 抛出异常
     *
     * @param errorEnum 错误枚举
     * @param arg 参数
     */
    private static void throwException(ErrorEnum errorEnum, Object... arg) {
        if (Objects.isNull(errorEnum)) {
            errorEnum = CommonErrorEnum.BUSINESS_ERROR;
        }
        throw new BusinessException(errorEnum.getErrorCode(), MessageFormat.format(errorEnum.getErrorMsg(), arg));
    }
}
